class Scope {
  constructor(options = {}) {
    this.name = options.name;
    this.parent = options.parent;
    this.names = options.params || [];//存放着这个作用域内的所有变量
    this.isBlockScope = !!options.block; //标志 当前作用域是否是一个块级作用域 （02.mini-rollup/lib/ast/analyse.js:  case 'BlockStatement' | case 'FunctionDeclaration'
  }

  /**
   *
   * @param name  添加变量
   * @param isBlockDeclaration  这个变量是否是块级声明 (let、const是 var不是)
   */
  add(name, isBlockDeclaration) {
    if (!isBlockDeclaration && this.isBlockScope /* { BlockScope } */) { //当前的作用域是一个块级作用域, 但当前声明的变量不是块级变量
      this.parent.add(name, isBlockDeclaration); //如果父作用域也是块级作用域的话 还会往上面插
    }else { //let const
      this.names.push(name);
    }
  }

  //↓ 也就找出依赖的外部变量时 用到了查找作用域 (analyse.js
  findDefiningScope(name) {
    if (this.names.includes(name)) {
      return this
    }
    if (this.parent) {
      return this.parent.findDefiningScope(name)
    }
    return null;
  }
}
module.exports = Scope;
